#include <iostream>
#include <unistd.h>
#include <fstream>
#include <string>
#include <map>
#include <mysql++.h>
#include <iomanip>
#include <algorithm>
#include <ctype.h>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <exception>

using namespace std;
using namespace mysqlpp;

//transform模板期望的类型为char，而tolower的参数是整型
//为了能通过编译器的类型检查，封装C的大小写转换函数
char mytolower (char c)
{
	return (char)tolower(c);
}

//将所有大写字母变成小写
char turn_tolower (char c)
{
	if (isupper(c))
	{
		c += 32;
	}
	return c;
}

//将所有非字母字符转换成空格
char turn_tospace (char c)
{
	//只要不是小写字母和换行一律转换成空格
	if (!islower(c) && '\n' != c)
	{
		c = ' ';
	}
	return c;
}

//对文本进行turn_tolower()和turn_tospace()的处理
//将处理过的文件内容放入后缀为.new的文件中
int pre_process (char* file_name)
{
	FILE* from_file;
	FILE* to_file;
	if ((from_file = fopen(file_name, "r") ) == NULL)
	{
		cout << __LINE__ << " failed open specified file~" << endl;
		return -1;
	}
	file_name = strcat(file_name, ".new");
	//cout << file_name << endl;
	//建立新.new文件
	if ((to_file = fopen( file_name, "w")) == NULL)
	{
		cout << __LINE__ << " fail~" << endl;
		return -1;
	}
	while (!feof(from_file))
	{
		char x = turn_tolower (fgetc(from_file));
		x = turn_tospace (x);
		fputc (x, to_file);
	}
	fclose(from_file);
	fclose(to_file);
	return 0;
}

//定义比较规则的函数
int cmp(const pair<string,int>& x,const pair<string,int>& y)
{
	return x.second < y.second;
}

//
void sortMapByValue(map<string,int>& tMap,vector<pair<string,int> >& tVector)
{
	for(map<string,int>::iterator curr=tMap.begin();curr!=tMap.end();curr++)
	{
		tVector.push_back(make_pair(curr->first,curr->second));
	}
	sort(tVector.begin(),tVector.end(),cmp);
}

//装载某一个难度级别的单词到内存中
int load_level_words (map <string, int> & words_level_map, string words_path, int words_level)
{
	ifstream obj_file (words_path.c_str());
	if (!obj_file)
	{
		cout << __LINE__ << " level 1 words file load fail!" << endl;
		//throw an exception
		return -1;	//使用异常的时候删除
	}
	string str, strs, stred, str_ing;
	while ( obj_file >> str )
	{
		//即使此单词在底一级出现过，只要在高一级再次出现，就赋予此单词高一级的难度值
		//因此此处不用判断以前此单词是否出现过
		words_level_map[str] = words_level;
		strs = str + "s";
		words_level_map[strs] = words_level;
		stred = str + "ed";
		words_level_map[stred] = words_level;
		str_ing = str + "ing";
		words_level_map[str_ing] = words_level;
	}
	obj_file.close();
	return 0;
}

//从数据库里加载所有单词的所有变形
int load_spellchecker (map <string, int> & all_words)
{
	try
	{
		Connection conn("spellchecker", "127.0.0.1", "root", "aids00a");
		Query query(conn.query());
		string temp;
		string sql = "select * from sc_dictionary;";
		if (UseQueryResult res = query.use(sql))
		{
			while (Row row = res.fetch_row())
			{
				row["word"].to_string(temp);
				all_words[temp] = 0;
			}
		}
		//conn.disconnect();
	}
	catch (const Exception& er)
	{
		cout << __LINE__ << er.what() << endl;
	}
	return 0;
}

int main (int argc, char* argv[]/* 从命令行读入的文件名 */)
{
	//char* path = (char*)"";
	char* file_name;// = strcat ( path, argv[1]);
	//cout << argv[1] << endl;
	//argv[1]的内容被pre_process函数改变，变成了.new文件
	pre_process(argv[1]);
	file_name = strcat(argv[1], "");
	//cout << __LINE__ << file_name <<  endl;
	ifstream obj_file (file_name);
	map <string, int> source_words, words_levels, all_words;
	//装载各个难度级别的单词到映射words_levels
	load_level_words (words_levels, "./words_levels/1.txt", 1);
	load_level_words (words_levels, "./words_levels/2.txt", 2);
	load_level_words (words_levels, "./words_levels/3.txt", 3);
	load_level_words (words_levels, "./words_levels/4.txt", 4);
	load_level_words (words_levels, "./words_levels/5.txt", 5);
	load_spellchecker (all_words);
	map <string, int>::iterator iter2levels, iter3levels;
	string str;
	//读入文件中的每个单词
	while (obj_file >> str)
	{
			if (str.size() > 1)
			{
					//拼写检查
					iter3levels = all_words.find(str);
					if ( all_words.end() != iter3levels )
					{
							//在载入的低等级词汇里找有没有这个单词
							iter2levels = words_levels.find(str);
							//如果单词不在低级词汇表里面（且拼写无误），则统计
							if (words_levels.end() == iter2levels /* &&  */)
							{
									if (source_words[str] == 0)
									{
											source_words[str] = 1;
									}
									else 
									{
											source_words[str]++; 
									}
							}
							else
							{
									//如果是低级词汇，以后扩展处理
							}
					}
			}
	}
	/*
	map<string, int>::iterator it;
	for ( it=source_words.begin() ; it != source_words.end(); it++ )
	{
		cout.width(20);
		cout << it->first;
		cout.width(5);
		cout << it->second << endl;
	}
	*/
	//cout << __LINE__ << str << endl;
	vector<pair<string,int> > tVector;
	sortMapByValue (source_words, tVector);
	vector <pair<string, int> >::iterator iter;
	for ( iter = tVector.begin(); iter != tVector.end(); iter++ )
	{
		//cout.width(18);
		cout << iter->first;
		//cout.width(10);
		//cout << iter->second;
		cout << endl;
	}

	obj_file.close();
	return 0;
}

